import { login, checkRole, register } from "@/api/admin"; // 引入请求
import { getToken, setToken, removeToken } from "@/utils/auth"; // 引入操作token的插件方法
import { resetRouter, constantRoutes } from "@/router"; // 重置路由，静态路由
import { generaMenu } from "@/utils/menus"; // 引入过滤权限路由表方法

// 封装了一个默认的state数据
const getDefaultState = () => {
  return {
    token: getToken(), // token
    userId: "", // id
    name: "", // 用户名
    avatar: "", // 头像
    menus: [], // 供addRoutes动态添加路由用的路由表
    routes: [] // 供侧边栏渲染用的路由表
  };
};

// 赋值默认state
const state = getDefaultState();

const mutations = {
  RESET_STATE: state => {
    Object.assign(state, getDefaultState()); // 用于清空重置state
  },
  SET_ID: (state, userId) => {
    state.userId = userId;
  },
  SET_TOKEN: (state, token) => {
    state.token = token; // 保存token用户令牌
  },
  SET_NAME: (state, name) => {
    state.name = name; // 保存昵称或用户名
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar; // 保存头像
  },
  SET_MENUS: (state, menus) => {
    state.menus = menus; // 保存供addRouter动态添加路由用的路由表
  },
  SET_ROUTES: (state, routes) => {
    state.routes = routes; // 保存供侧边栏渲染用的路由表
  }
};

const actions = {
  // 用户登录
  login({ commit }, userInfo) {
    const { username, password } = userInfo;
    return new Promise((resolve, reject) => {
      login({
        username: username.trim(),
        password: password
      })
        .then(response => {
          const { token } = response.data;
          // localStorage/sessionStorage 他们均只能存储字符串类型的对象
          /**
           * localStorage生命周期是永久，
           * 除非用户清除localStorage信息，
           * 否则这些信息将永远存在
           */

          /**
           * sessionStorage生命周期为当前窗口或标签页，
           * 一旦窗口或标签页被永久关闭了，
           * 那么所有通过它存储的数据也就被清空了
           */
          // sessionStorage.setItem("userId", userInfo.id); // 保存 用户id 到浏览器session缓存
          // localStorage.setItem("userId", userInfo.id); // 保存 用户id 到浏览器local缓存
          commit("SET_TOKEN", token); // 保存token
          setToken(token); // 使用Cookies插件保存token
          resolve();
        })
        .catch(error => {
          reject(error);
        });
    });
  },

  // 用户的权限路由表
  checkRole({ commit, dispatch }) {
    return new Promise((resolve, reject) => {
      checkRole().then(response => {
        const { data } = response;
        if (!data) {
          dispatch("logout");
          reject("验证失败，请重新登录。");
          return;
        }
        const { id, username, avatar } = data.userInfo;
        // 保存用户信息
        commit("SET_NAME", username); // 保存用户昵称
        commit("SET_AVATAR", avatar); // 保存用户头像
        commit("SET_ID", id); // 保存用户id
        const menus = data.routers; // 获取未过滤的路由表
        const def = {
          path: "*",
          redirect: "/404",
          hidden: true
        }; // 最后添加的404页面重定向

        /**
         * newRouter与repRouter互相不影响
         * newRouter：供addRoutes动态添加路由用的路由表
         * repRouter：供侧边栏渲染用的路由表
         */
        const newRouter = generaMenu(menus).concat(def); // 用封装好的generaMenu()过滤路由，并最后添加404路由
        commit("SET_MENUS", newRouter); // 保存过滤好的路由,等待addRoutes添加
        const repRouter = constantRoutes.concat(newRouter); // 添加到侧边栏渲染的路由表
        commit("SET_ROUTES", repRouter); // 保存供侧边栏渲染的路由表
        resolve();
      });
    });
  },

  // 用户登出
  logout({ commit,dispatch }) {
    return new Promise((resolve, reject) => {
      // logout(state.token).then(response => {});
      removeToken(); // 清除token
      resetRouter(); // 登出需要重置路由权限
      commit("RESET_STATE"); // 重置state数据
      commit(
        "user/SET_USER_INFO",
        {},
        {
          root: true
        }
      ); // 清空user模块共享的用户信息
      dispatch(
        "tagsView/delAllViews",
        {},
        {
          root: true
        }
      ); // 清空tab
      sessionStorage.clear(); // 删除所有sessionStorage缓存
      localStorage.clear(); // 删除所有localStorage缓存
      resolve();
    });
  },

  // 清除token
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken(); // 清除token
      commit("RESET_STATE"); // 清空state共享的数据
      resolve();
    });
  },

  // 注册
  register({ commit }, data) {
    return new Promise((resolve, reject) => {
      register(data)
        .then(response => {
          resolve(response);
        })
        .catch(error => {
          reject(error);
        });
    });
  }
};

export default {
  namespaced: true, // 命名空间
  state,
  mutations,
  actions
};
